package com.pro01.backend.service;

import com.pro01.backend.dto.LoginResponseDTO;
import com.pro01.backend.mapper.*;
import com.pro01.backend.pojo.EmailVerification;
import com.pro01.backend.pojo.PageResult;
import com.pro01.backend.pojo.User;
import com.pro01.backend.pojo.UserInvite;
import com.pro01.backend.utils.JwtUtil;
import com.pro01.backend.utils.Md5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserInviteMapper userInviteMapper;
    @Autowired
    private EmailVerificationMapper emailVerificationMapper;
    @Autowired
    private TorrentMapper torrentMapper;
    @Autowired
    private TorrentDownloadMapper torrentDownloadMapper;
    @Autowired
    private PointService pointService;


    public User getUserById(Long id) {
        return userMapper.getUserSafeInfoById(id);
    }

    public User getUserSafeInfoById(Long id){
        return userMapper.getUserSafeInfoById(id);
    }

//    public List<User> getAllUsers() {
//        return userMapper.getAllUsers();
//    }

    //管理员分页查看所有用户信息
    public PageResult<User> getUsersPaged(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<User> users = userMapper.getUsersPaged(offset, pageSize);
        int total = userMapper.countUsers();
        return new PageResult<>(total, users);
    }



    public int updateUser(User user) {
        return userMapper.updateUser(user);
    }

    public int banUser(Long id) {
        return userMapper.banUser(id);
    }

    public int unbanUser(Long id) {
        return userMapper.unbanUser(id);
    }

    public int deleteUser(Long id) {
        return userMapper.deleteUser(id);
    }

    /**
     * 用户注册
     */
    @Transactional
    public boolean register(String username, String password, String email, String inviteCode, String emailCode) {
        // 1. 验证邀请码
        UserInvite invite = userInviteMapper.getValidInvite(inviteCode);
        if (invite == null) {
            throw new RuntimeException("邀请码无效或已被使用");
        }

        // 2. 验证邮箱验证码是否正确且未过期
        EmailVerification verification = emailVerificationMapper.getLatestCode(email);
        if (verification == null || !verification.getCode().equals(emailCode)) {
            throw new RuntimeException("邮箱验证码错误");
        }

        // 3. 检查用户名是否已存在
        if (userMapper.getUserByUsername(username) != null) {
            throw new RuntimeException("用户名已被注册");
        }

        // 4. 使用 MD5 加密密码
        String hashedPassword = Md5Util.getMD5String(password);

        // ✅ 5. 生成唯一的 passkey
        String passkey = UUID.randomUUID().toString().replace("-", "");

        // 6. 插入新用户
        User newUser = new User();
        newUser.setUsername(username);
        newUser.setPassword(hashedPassword);
        newUser.setEmail(email);
        newUser.setRole("USER");  // ✅ 设置默认角色

        // ✅ 新增字段赋默认值
        newUser.setCredit(0L);          // 贡献值
        newUser.setVirtualRatio(0.0f);  // 虚拟分享率
        newUser.setLevel("新手");         // 默认等级
        newUser.setUploadCount(0);      // 上传次数
        newUser.setDownloadCount(0);    // 下载次数
        newUser.setStatus("ACTIVE");    // 用户状态
        //newUser.setPasskey(passkey);    // 唯一识别码
        newUser.setPasskey(passkey); // ✅ 添加 passkey 字段

        userMapper.insertUser(newUser);

        // 6. 标记邀请码为已使用
        userInviteMapper.markInviteAsUsed(inviteCode);

        // 7. 删除验证码，防止重复使用
        emailVerificationMapper.deleteEmailCode(email);

        return true;
    }

    /**
     * 用户登录（支持用户名或邮箱登录）
     */

//    public Map.Entry<String, String> login(String identifier, String password) {
//        // 1. 查找用户（支持邮箱或用户名登录）
//        User user = userMapper.getUserByUsername(identifier);
//        if (user == null) {
//            user = userMapper.getUserByEmail(identifier);
//            if (user == null) {
//                throw new RuntimeException("用户不存在");
//            }
//        }
//
//        // 2. 验证密码
//        if (!Md5Util.checkPassword(password, user.getPassword())) {
//            throw new RuntimeException("密码错误");
//        }
//
//        // 3. 检查账户状态
//        if ("BANNED".equals(user.getStatus())) {
//            throw new RuntimeException("该账户已被封禁，请联系管理员");
//        }
//
//        // 登录奖励与等级刷新
//        refreshCreditAndLevel(user.getId());
//        pointService.addLoginReward(user.getId());
//
//        // 生成 JWT
//        Map<String, Object> claims = new HashMap<>();
//        claims.put("userId", user.getId());
//        claims.put("username", user.getUsername());
//        claims.put("role", user.getRole());
//
//        String token = JwtUtil.genToken(claims);
//        return new AbstractMap.SimpleEntry<>(token, user.getRole());
//    }

    public LoginResponseDTO login(String identifier, String password) {
        // 1. 查找用户（支持邮箱或用户名登录）
        User user = userMapper.getUserByUsername(identifier);
        if (user == null) {
            user = userMapper.getUserByEmail(identifier);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }
        }

        // 2. 验证密码
        if (!Md5Util.checkPassword(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        // 3. 检查账户状态
        if ("BANNED".equals(user.getStatus())) {
            throw new RuntimeException("该账户已被封禁，请联系管理员");
        }

        // 登录奖励与等级刷新
        refreshCreditAndLevel(user.getId());
        pointService.addLoginReward(user.getId());

        // 生成 JWT
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("username", user.getUsername());
        claims.put("role", user.getRole());

        String token = JwtUtil.genToken(claims);

        // 构造 DTO：判断是否拥有幸运头像框
        boolean hasLuckyFrame = "lucky_frame".equals(user.getAvatarFrame());
        return new LoginResponseDTO(token, user.getRole(), hasLuckyFrame);
    }


    /**
     * 刷新用户贡献值、虚拟分享率、等级
     */
    /*
    public boolean refreshCreditAndLevel(Long userId) {
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 计算贡献值
        int uploadCount = torrentMapper.countUserUploadedTorrents(userId);
        int downloadCount = torrentDownloadMapper.countUserDownloadedTorrents(userId);

        long credit = (10L * uploadCount) + (5L * downloadCount);

        // 计算虚拟分享率
        float virtualRatio = (float) uploadCount / (downloadCount + 1); // 防止除0

        // 判断等级
        String level;
        if (credit >= 700) {
            level = "高级用户";
        } else if (credit >= 300) {
            level = "进阶用户";
        } else if (credit >= 100) {
            level = "普通用户";
        } else {
            level = "新手";
        }

        // 更新到数据库
        //return userMapper.updateCreditAndLevel(userId, credit, virtualRatio, level) > 0;
        // 更新到数据库（包括 upload_count 和 download_count）
        return userMapper.updateCreditAndLevelAndCounts(userId, credit, virtualRatio, level, uploadCount, downloadCount) > 0;
    }
     */
    /*
    public boolean refreshCreditAndLevel(Long userId) {
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 读取真实上传/下载次数
        int realUploadCount = torrentMapper.countUserUploadedTorrents(userId);
        int realDownloadCount = torrentDownloadMapper.countUserDownloadedTorrents(userId);

        // 读取 bonus 加成
        int bonusUpload = user.getBonusUpload();      // 上传加成
        int bonusDownload = user.getBonusDownload();  // 减少下载次数
        long bonusCredit = user.getBonusCredit();      // 贡献值加成

        // 加权后的上传/下载次数
        int effectiveUploadCount = realUploadCount + bonusUpload;
        int effectiveDownloadCount = realDownloadCount - bonusDownload;
        if (effectiveDownloadCount < 0) effectiveDownloadCount = 0; // 防止负数

        // 计算贡献值
        long credit = (10L * effectiveUploadCount) + (5L * realDownloadCount) + bonusCredit;

        // 计算虚拟分享率
        float virtualRatio = (float) effectiveUploadCount / (effectiveDownloadCount + 1); // 防止除0

        // 判断等级
        String level;
        if (credit >= 700) {
            level = "高级用户";
        } else if (credit >= 300) {
            level = "进阶用户";
        } else if (credit >= 100) {
            level = "普通用户";
        } else {
            level = "新手";
        }

        // 更新到数据库（upload_count、download_count 也一起刷新）
        return userMapper.updateCreditAndLevelAndCounts(
                userId,
                credit,
                virtualRatio,
                level,
                realUploadCount,
                realDownloadCount
        ) > 0;
    }
     */
    public boolean refreshCreditAndLevel(Long userId) {
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 计算上传/下载次数
        int uploadCount = torrentMapper.countUserUploadedTorrents(userId);
        int downloadCount = torrentDownloadMapper.countUserDownloadedTorrents(userId);

        // 计算贡献值，应用促销加成
        long credit = (10L * (uploadCount + user.getBonusUpload()))
                + (5L * (downloadCount - user.getBonusDownload()))
                + user.getBonusCredit();

        // 计算虚拟分享率
        float virtualRatio = (float) (uploadCount + user.getBonusUpload()) / (downloadCount - user.getBonusDownload() + 1);

        // 判断等级
        String level;
        if (credit >= 700) {
            level = "高级用户";
        } else if (credit >= 300) {
            level = "进阶用户";
        } else if (credit >= 100) {
            level = "普通用户";
        } else {
            level = "新手";
        }

        // 更新到数据库
        boolean updated = userMapper.updateCreditAndLevelAndCounts(userId, credit, virtualRatio, level, uploadCount, downloadCount) > 0;

        if (updated) {
            System.out.println(String.format(
                    "✅ 刷新成功：用户ID=%d，用户名=%s，贡献值=%d，虚拟分享率=%.2f，等级=%s",
                    userId, user.getUsername(), credit, virtualRatio, level
            ));
        } else {
            System.err.println("❌ 刷新失败：用户ID=" + userId);
        }

        return updated;
    }



    //批量刷新所有用户的贡献值、虚拟分享率、等级
    /*
    public void refreshAllUsersCreditAndLevel() {
        List<User> users = userMapper.getAllUsers();
        for (User user : users) {
            refreshCreditAndLevel(user.getId());
        }
    }
     */
    public void refreshAllUsersCreditAndLevel() {
        List<User> users = userMapper.getAllUsers();
        for (User user : users) {
            try {
                refreshCreditAndLevel(user.getId());
            } catch (Exception e) {
                System.err.println("刷新用户ID " + user.getId() + " 失败：" + e.getMessage());
                // 可以记录日志或者继续
            }
        }
    }


    public int getTodayRemainingDownloads(Long userId) {
        // 获取今天已下载次数
        int todayDownloads = torrentDownloadMapper.countUserTodayDownloads(userId);

        // 查询用户等级
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        int maxDownloads;
        switch (user.getLevel()) {
            case "新手":
                maxDownloads = 3;
                break;
            case "普通用户":
                maxDownloads = 10;
                break;
            case "进阶用户":
                maxDownloads =30;
                break;
            case "高级用户":
                return Integer.MAX_VALUE; // 高级用户不限下载
            default:
                maxDownloads = 3; // 默认当成新手
        }

        return Math.max(0, maxDownloads - todayDownloads);
    }


    //下面是模糊查询用户的方法
    /*
    public List<User> searchUsersByUsername(String keyword, int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        return userMapper.searchUsersByUsername(keyword, offset, pageSize);
    }
     */
    public PageResult<User> searchUsersByUsernameWithTotal(String keyword, int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<User> users = userMapper.searchUsersByUsername(keyword, offset, pageSize);
        int total = userMapper.countUsersByUsername(keyword);

        PageResult<User> pageResult = new PageResult<>();
        pageResult.setRecords(users);
        pageResult.setTotal(total);
        return pageResult;
    }


    /**
     * 修改密码
     */
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        // 1. 查找用户
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 2. 验证旧密码
        if (!Md5Util.checkPassword(oldPassword, user.getPassword())) {
            throw new RuntimeException("旧密码错误");
        }

        // 3. 更新密码
        String hashedNewPassword = Md5Util.getMD5String(newPassword);
        return userMapper.updatePassword(userId, hashedNewPassword) > 0;
    }

    public boolean updateUsername(Long userId, String newUsername) {
        // 判断用户名是否已存在
        if (userMapper.existsByUsername(newUsername)) {
            throw new RuntimeException("用户名已存在");
        }

        // 更新用户名
        return userMapper.updateUsername(userId, newUsername) > 0;
    }

    /**
     * 查询用户今天下载了多少次(仅限管理员)
     */
    public int getTodayDownloadsByUserId(Long userId) {
        return torrentDownloadMapper.countTodayDownloadsByUserId(userId);
    }

    /**
     * 查询所有用户的下载次数(仅限管理员)
     */
//    public List<Map<String, Object>> getAllUsersDownloadCounts() {
//        return torrentDownloadMapper.countAllUsersDownloadsWithUsername();
//    }
    // 分页查询所有用户的下载次数
    public PageResult<Map<String, Object>> getAllUsersDownloadCountsPaged(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Map<String, Object>> result = torrentDownloadMapper.countAllUsersDownloadsPaged(offset, pageSize);
        int total = userMapper.countUsers(); // 总数可以直接用 users 表统计

        PageResult<Map<String, Object>> pageResult = new PageResult<>();
        pageResult.setRecords(result);
        pageResult.setTotal(total);
        return pageResult;
    }


    /**
     * 查询所有用户的上传次数(仅限管理员)
     */
//    public List<Map<String, Object>> getAllUsersUploadCounts() {
//        return torrentMapper.countAllUsersUploadsWithUsername();
//    }
    // 分页查询所有用户的上传次数
    public PageResult<Map<String, Object>> getAllUsersUploadCountsPaged(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Map<String, Object>> result = torrentMapper.countAllUsersUploadsPaged(offset, pageSize);
        int total = userMapper.countUsers(); // 这里直接统计 users 表人数

        PageResult<Map<String, Object>> pageResult = new PageResult<>();
        pageResult.setRecords(result);
        pageResult.setTotal(total);
        return pageResult;
    }

    /**
     * 查询所有用户的贡献值和等级(仅限管理员)
     */
//    public List<Map<String, Object>> getAllUsersCreditAndLevel() {
//        return userMapper.getAllUsersCreditAndLevel();
//    }
    public PageResult<Map<String, Object>> getAllUsersCreditAndLevelPaged(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Map<String, Object>> list = userMapper.getAllUsersCreditAndLevelPaged(offset, pageSize);
        int total = userMapper.countAllUsers();
        return new PageResult<>(total, list);
    }

    /**
     * 查询所有用户的准分享率(仅限管理员)
     */
//    public List<Map<String, Object>> getAllUsersVirtualRatio() {
//        return userMapper.getAllUsersVirtualRatio();
//    }
    // 分页查询所有用户准分享率
    public PageResult<Map<String, Object>> getAllUsersVirtualRatioPaged(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Map<String, Object>> users = userMapper.getUsersVirtualRatioPaged(offset, pageSize);
        int total = userMapper.countUsers();

        PageResult<Map<String, Object>> result = new PageResult<>();
        result.setRecords(users);
        result.setTotal(total);
        return result;
    }


    /**
     * 查询指定用户的所有信息(仅限管理员)
     */
    public Map<String, Object> getSafeUserInfoById(Long id) {
        return userMapper.getSafeUserInfoById(id);
    }

    /**
     * 提拔用户为管理员(仅限管理员)
     */
    public boolean promoteToAdmin(Long userId) {
        // 1. 查找用户
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 2. 确保用户当前是 USER，而不是 ADMIN
        if ("ADMIN".equals(user.getRole())) {
            throw new RuntimeException("该用户已是管理员");
        }

        // 3. 更新用户角色
        return userMapper.updateRole(userId) > 0;
    }

    /**
     * 降级用户为普通用户(仅限管理员)
     */
    public boolean demoteToUser(Long userId) {
        // 1. 查找用户
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 2. 确保用户当前是 `ADMIN`
        if (!"ADMIN".equals(user.getRole())) {
            throw new RuntimeException("该用户不是管理员，无法降级");
        }

        // 3. 更新用户角色为 `USER`
        return userMapper.updateRoleToUser(userId) > 0;
    }

    /**
     * 警告用户(仅限管理员)
     */
    public boolean warnUser(Long userId) {
        // 1. 查找用户
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 2. 确保用户当前不是已经 `WARNED`
        if ("WARNED".equals(user.getStatus())) {
            throw new RuntimeException("该用户已被警告");
        }

        // 3. 更新用户状态
        return userMapper.updateStatus(userId) > 0;
    }

    /**
     * 解除警告(仅限管理员)
     */
    public boolean removeWarning(Long userId) {
        // 1. 查找用户
        User user = userMapper.getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 2. 确保用户当前是 `WARNED`
        if (!"WARNED".equals(user.getStatus())) {
            throw new RuntimeException("该用户未被警告，无法解除");
        }

        // 3. 更新用户状态为 `ACTIVE`
        return userMapper.updateStatusToActive(userId) > 0;
    }

    /**
     * 验证 JWT Token
     */
    public boolean validateToken(String token) {
        try {
            Map<String, Object> claims = JwtUtil.parseToken(token);
            return claims != null && claims.containsKey("id");
        } catch (Exception e) {
            return false;
        }
    }
}
